Skip to content

戦略的決定

最新のゲーム状態を利用して、あなたのボットは「自律エージェント」に進化することができます。この移行は機能の向上を示しており、ゲーム状態に反応するだけでなく、文脈、エネルギー、近接性を考慮して戦略的な行動を決定します。

コードを書く

bot.luaファイルに戻り、次の関数を追加します。

lua
-- Determines proximity between two points.
function inRange(x1, y1, x2, y2, range)
    return math.abs(x1 - x2) <= range and math.abs(y1 - y2) <= range
end

-- Strategically decides on the next move based on proximity and energy.
function decideNextAction()
  local player = LatestGameState.Players[ao.id]
  local targetInRange = false

  for target, state in pairs(LatestGameState.Players) do
      if target ~= ao.id and inRange(player.x, player.y, state.x, state.y, 1) then
          targetInRange = true
          break
      end
  end

  if player.energy > 5 and targetInRange then
    print("Player in range. Attacking.")
    ao.send({Target = Game, Action = "PlayerAttack", Player = ao.id, AttackEnergy = tostring(player.energy)})
  else
    print("No player in range or insufficient energy. Moving randomly.")
    local directionMap = {"Up", "Down", "Left", "Right", "UpRight", "UpLeft", "DownRight", "DownLeft"}
    local randomIndex = math.random(#directionMap)
    ao.send({Target = Game, Action = "PlayerMove", Player = ao.id, Direction = directionMap[randomIndex]})
  end
end

The decideNextAction関数は、エージェントがその環境を包括的に理解した上で思考し、行動する能力を証明するものとなりました。この関数は、最新のゲーム状態を分析し、エネルギーが十分で、かつ相手がinRangeにいる場合に攻撃するか、そうでない場合は移動します。

この関数が自動的に実行されるようにするためには、ハンドラーが必要です。

lua
Handlers.add(
  "decideNextAction",
  { Action = "UpdatedGameState" },
  function ()
    if LatestGameState.GameMode ~= "Playing" then
      return
    end
    print("Deciding next action.")
    decideNextAction()
  end
)

このハンドラーは、最新のゲーム状態が取得され更新されたことを示すメッセージを受信した際にトリガーされます。アクションは、ゲームがPlayingモードのときのみ実行されます。

以下のドロップダウンで、bot.luaの最新のコードを参照できます:

Updated bot.lua file
lua
LatestGameState = LatestGameState or nil

function inRange(x1, y1, x2, y2, range)
    return math.abs(x1 - x2) <= range and math.abs(y1 - y2) <= range
end

function decideNextAction()
  local player = LatestGameState.Players[ao.id]
  local targetInRange = false

  for target, state in pairs(LatestGameState.Players) do
      if target ~= ao.id and inRange(player.x, player.y, state.x, state.y, 1) then
          targetInRange = true
          break
      end
  end

  if player.energy > 5 and targetInRange then
    print("Player in range. Attacking.")
    ao.send({Target = Game, Action = "PlayerAttack", Player = ao.id, AttackEnergy = tostring(player.energy)})
  else
    print("No player in range or insufficient energy. Moving randomly.")
    local directionMap = {"Up", "Down", "Left", "Right", "UpRight", "UpLeft", "DownRight", "DownLeft"}
    local randomIndex = math.random(#directionMap)
    ao.send({Target = Game, Action = "PlayerMove", Player = ao.id, Direction = directionMap[randomIndex]})
  end
end

Handlers.add(
"HandleAnnouncements",
{ Action = "Announcement" },
function (msg)
  ao.send({Target = Game, Action = "GetGameState"})
  print(msg.Event .. ": " .. msg.Data)
end
)

Handlers.add(
"UpdateGameState",
{ Action = "GameState" },
function (msg)
  local json = require("json")
  LatestGameState = json.decode(msg.Data)
  ao.send({Target = ao.id, Action = "UpdatedGameState"})
end
)

Handlers.add(
"decideNextAction",
{ Action = "UpdatedGameState" },
function ()
  if LatestGameState.GameMode ~= "Playing" then
    return
  end
  print("Deciding next action.")
  decideNextAction()
end
)

ローディングとテスト

もう一度、最新のアップグレードをテストするために、次のようにしてファイルをあなたの aos プレイヤー端末にロードします:

lua
.load bot.lua

あなたのプロセスの出力を観察して、自律エージェントがリアルタイムでどのように決定を下すかを確認してください。しかし、別のプレイヤーが攻撃し、あなたが次の動きを決定している間に逃げてしまったらどうしますか?次のセクションでは、攻撃された瞬間に自動的に反撃する方法を学びます🤺